package com.laomou.logdog.loginfo;

import java.util.StringTokenizer;

public class LogInfoParser {

    public LogInfo processLogLine(String strlog) {
        if (isNormalLog(strlog)) {
            return parseNormalLog(strlog);
        } else if (isThreadTimeLog(strlog)) {
            return parseThreadTime(strlog);
        } else if(isKernel(strlog)) {
            return getKernel(strlog);
        } else {
            LogInfo logInfo = new LogInfo();
            logInfo.setMessage(strlog);
            return logInfo;
        }
    }

    /**
     * adb logcat
     *
     * @param strlog
     * @return
     */
    private boolean isNormalLog(String strlog) {
        if (strlog.length() < 22) {
            return false;
        }
        String strLevel = strlog.substring(19, 21);
        if ((strLevel.equals("D/")) || (strLevel.equals("V/"))
                || (strLevel.equals("I/")) || (strLevel.equals("W/"))
                || (strLevel.equals("E/")) || (strLevel.equals("F/"))) {
            return true;
        }
        return false;
    }

    /**
     * adb logcat -v time/threadtime
     *
     * @param strlog
     * @return
     */
    private boolean isThreadTimeLog(String strlog) {
        if (strlog.length() < 34) {
            return false;
        }
        String strLevel = strlog.substring(31, 33);
        if ((strLevel.equals("D ")) || (strLevel.equals("V "))
                || (strLevel.equals("I ")) || (strLevel.equals("W "))
                || (strLevel.equals("E ")) || (strLevel.equals("F "))) {
            return true;
        }
        if (strlog.length() < 37) {
            return false;
        }
        strLevel = strlog.substring(34, 36);
        if ((strLevel.equals("D ")) || (strLevel.equals("V "))
                || (strLevel.equals("I ")) || (strLevel.equals("W "))
                || (strLevel.equals("E ")) || (strLevel.equals("F "))) {
            return true;
        }
        return false;
    }

    /**
     * adb shell cat /proc/kmsg
     *
     * @param strlog
     * @return
     */
    private boolean isKernel(String strlog) {
        if(strlog.length() < 18) return false;

        String strLevel = strlog.substring(1, 2);
        if(strLevel.equals("0")
                || strLevel.equals("1")
                || strLevel.equals("2")
                || strLevel.equals("3")
                || strLevel.equals("4")
                || strLevel.equals("5")
                || strLevel.equals("6")
                || strLevel.equals("7")
                )
            return true;
        return false;
    }

    private LogInfo parseNormalLog(String strlog) {
        LogInfo logInfo = new LogInfo();

        StringTokenizer stk = new StringTokenizer(strlog, "/() ", false);
        if (stk.hasMoreElements()) {
            logInfo.setDate(stk.nextToken());
        }
        if (stk.hasMoreElements()) {
            logInfo.setTime(stk.nextToken());
        }
        if (stk.hasMoreElements()) {
            logInfo.setLogLv(stk.nextToken().trim());
        }
        if (stk.hasMoreElements()) {
            logInfo.setTag(stk.nextToken());
        }
        if (stk.hasMoreElements()) {
            logInfo.setPid(stk.nextToken().trim());
        }
        String message;
        if (stk.hasMoreElements()) {
            message = stk.nextToken("'");
            while (stk.hasMoreElements()) {
                message += stk.nextToken("'");
            }
            message = message.replaceFirst("\\): ", "");
            logInfo.setMessage(message);
        }
        return logInfo;
    }

    private LogInfo parseThreadTime(String strlog) {
        LogInfo logInfo = new LogInfo();

        StringTokenizer stk = new StringTokenizer(strlog, " ", false);
        if (stk.hasMoreElements()) {
            logInfo.setDate(stk.nextToken());
        }
        if (stk.hasMoreElements()) {
            logInfo.setTime(stk.nextToken());
        }
        if (stk.hasMoreElements()) {
            logInfo.setPid(stk.nextToken().trim());
        }
        if (stk.hasMoreElements()) {
            logInfo.setTid(stk.nextToken().trim());
        }
        if (stk.hasMoreElements()) {
            logInfo.setLogLv(stk.nextToken().trim());
        }
        if (stk.hasMoreElements()) {
            logInfo.setTag(stk.nextToken());
        }
        String message;
        if (stk.hasMoreElements()) {
            message = stk.nextToken("'");
            while (stk.hasMoreElements()) {
                message += stk.nextToken("'");
            }
            message = message.replaceFirst("\\): ", "");
            logInfo.setMessage(message);
        }
        return logInfo;
    }

    private LogInfo getKernel(String strlog) {
        LogInfo logInfo = new LogInfo();

        StringTokenizer stk = new StringTokenizer(strlog, "<>[]", false);
        if(stk.hasMoreElements()) {
            logInfo.setLogLv(stk.nextToken());
        }
        if(stk.hasMoreElements()) {
            logInfo.setTime(stk.nextToken());
        }
        String message;
        if(stk.hasMoreElements()) {
            message = stk.nextToken("<>[]");
            while(stk.hasMoreElements()) {
                message += " " + stk.nextToken(" ");
            }
            message = message.replaceFirst("  ", "");
            logInfo.setMessage(message);
        }
        return logInfo;
    }

    public static void main(String[] args) {
        System.out.println(new LogInfoParser().processLogLine("03-21 00:23:17.199 I/AEE/AED (13146): Exception Type: SIGFPE").toString());
    }

}
